package top.chukongxiang.dubboboot.simple.common.utils;

import com.alibaba.fastjson.JSONArray;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public final class ObjectUtils {

    public static final List<Class<?>> SIMPLE_CLASSES = new ArrayList<>();

    static {
        SIMPLE_CLASSES.add(String.class);
        SIMPLE_CLASSES.add(Integer.class);
        SIMPLE_CLASSES.add(int.class);
        SIMPLE_CLASSES.add(Character.class);
        SIMPLE_CLASSES.add(char.class);
        SIMPLE_CLASSES.add(Long.class);
        SIMPLE_CLASSES.add(long.class);
        SIMPLE_CLASSES.add(Short.class);
        SIMPLE_CLASSES.add(short.class);
        SIMPLE_CLASSES.add(Byte.class);
        SIMPLE_CLASSES.add(byte.class);
        SIMPLE_CLASSES.add(Double.class);
        SIMPLE_CLASSES.add(double.class);
        SIMPLE_CLASSES.add(Float.class);
        SIMPLE_CLASSES.add(float.class);
        SIMPLE_CLASSES.add(Boolean.class);
        SIMPLE_CLASSES.add(boolean.class);
    }

    public static Object getObjectFromBytes(byte[] objBytes) throws Exception {
        if(objBytes != null && objBytes.length != 0) {
            ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
            ObjectInputStream oi = new ObjectInputStream(bi);
            return oi.readObject();
        } else {
            return null;
        }
    }

    public static byte[] getBytesFromObject(Object obj) throws Exception {
        if(obj == null) {
            return null;
        } else {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            return bo.toByteArray();
        }
    }

    public static Object getValue(String fieldName,Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        for(Field field:fields){
            String name = field.getName();
            if(fieldName.equals(name)){
                try {
                    return field.get(clazz);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }
        return null;
    }



    /** 判断一个对象是否是基本类型 **/
    public static boolean isPrimitive(Type type) {
        try {
            return isPrimitive(Class.forName(type.getTypeName()));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean isPrimitive(Class<?> clazz) {
        try {
            return SIMPLE_CLASSES.contains(clazz);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static Object parseSimple(Type type, String string) throws ClassNotFoundException {
        if (type==null || StringUtils.isEmpty(string) || !isPrimitive(type)) {
            return null;
        }
        return Parse.parsePrimitive(string, Class.forName(type.getTypeName()));
    }
    public static Object parseSimple(Class<?> clazz, String string) {
        if (clazz==null || StringUtils.isEmpty(string) || !isPrimitive(clazz)) {
            return null;
        }
        return Parse.parsePrimitive(string, clazz);
    }
    public static boolean isPrimitive(Object obj) {
        try {
            return ((Class<?>)obj.getClass().getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            return false;
        }
    }

    static class Parse{

        /**
         * String转主数据类型
         * @param string 字符串
         * @param clazz 目标类型class
         * @return
         */
        public static Object parsePrimitive(String string, Class<?> clazz){
            if (clazz==String.class) {
                return string;
            } else if (clazz==Long.class || clazz==long.class) {
                return Long.valueOf(string);
            } else if (clazz==Integer.class || clazz==int.class) {
                return Integer.valueOf(string);
            } else if (clazz==Boolean.class || clazz==boolean.class) {
                return Boolean.valueOf(string);
            } else if (clazz==Character.class || clazz==char.class) {
                return string.charAt(0);
            } else if (clazz==Double.class || clazz==double.class) {
                return Double.valueOf(string);
            } else if (clazz==Float.class || clazz==float.class) {
                return Float.valueOf(string);
            }
            return null;
        }

        /**
         * String转集合类型
         * @param str
         * @param listType
         * @return
         */
        public static Collection<Object> parseCollection(String str, Type listType){
            ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) listType;
            //获取到list到泛型
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            return JSONArray.parseArray(str,actualTypeArguments);
        }
    }

    

}
